﻿#region License
/*

	Copyright (C) 2008 Oliver Charles, Daniel Hollander

	This program is free software: you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.

	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with this program.  If not, see <http://www.gnu.org/licenses/>.
	
*/
#endregion

using System;
using System.Drawing;
using Moebius.Core;
using Moebius.Input;
using Moebius.Rendering.OpenGL;
using Overload.Entities;

[assembly:CLSCompliant(true)]
namespace Overload
{
    static class Game
    {
        [STAThread]
        static void Main()
        {
            ConsoleLogger logger = new ConsoleLogger();
            Engine engine = new Engine();
            engine.Logger = logger;

            Renderer renderer = new Renderer();
            InputHandler input = new InputHandler();
            input.Logger = logger;

            engine.Initialize(renderer, input, "Overload");
	    engine.ResourceFactory.Logger = logger;

            World world = World.LoadWorld("Resources/Tiletypes.xml", "Resources/firstMap.bmp");
            world.Initialize(engine.ResourceFactory);

            engine.AddTask(world);

            world.RegisterSubsystem(typeof(Moebius.Components.Image), renderer.Subsystem);

            // Debug!
            engine.AddTask(new State(input, world, world.Terrain, logger));
            // ----

			logger.LogInfo("Everything is initialized; proceeding to take over the world!");
			engine.Run();
        }
    }

    public class State : Task
    {
        private readonly InputHandler handler;
        private readonly DebugThing debugger;
        private readonly Terrain terrain;
        private readonly World world;
        private readonly ILogger logger;

        public State(InputHandler input, World world, Terrain terrain, ILogger logger)
        {
            handler = input;
            this.logger = logger;
            handler.MouseClicked += OnMouseClick;
            this.terrain = terrain;
            debugger = new DebugThing(world);
            this.world = world;
        }

        void OnMouseClick(object sender, EventArgs e)
        {
            Squad squad = new Squad(world);
            // We should be able to give units just a tile position
            try
            {
                Point tileCoordinates = terrain.CalculateTileCoordinatesFromScreenSpace(handler.MouseLocation);
                world.CurrentPhase.PlaceUnit(squad, tileCoordinates);
            }
            catch (InvalidLocationException)
            {
                logger.LogInfo("Invalid location");
                world.RemoveEntity(squad);
            }
        }

        public override void Execute(double elapsedTime)
        {
            Point tileCoords = terrain.CalculateTileCoordinatesFromScreenSpace(handler.MouseLocation);
            RectangleF screenSpace = terrain.CalculateTileScreenPosition(tileCoords);

            debugger.Position = screenSpace.Location;
        }
    }
}
